package logic

import (
	"context"
	"encoding/json"
	"fmt"
	"time"

	"googee/common/errorx"
	"googee/common/utils"
	"googee/service/task/api/internal/svc"
	"googee/service/task/api/internal/types"
	"googee/service/task/model"

	"github.com/jinzhu/copier"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

type GroupLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGroupLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GroupLogic {
	return &GroupLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *GroupLogic) Group(req *types.GroupReq) (resp *types.GroupReply, err error) {
	resp = &types.GroupReply{}

	id, err := l.ctx.Value("userId").(json.Number).Int64()
	if err != nil {
		return nil, err
	}

	//获得所有配置数据的内容
	conditions, err := l.svcCtx.ConditionConfigModel.FindAll(l.ctx)
	if err != nil {
		return nil, errorx.NewCodeErrorNoMsg(errorx.TASK_ERROR + 2)
	}

	//生成cond map表
	cond_map := make(map[string]string)
	for _, cond := range conditions {
		cond_map[cond.Name] = cond.Desc
	}

	//获得当前分组所有配置的条件
	task_conds_data := []*types.TaskCondition{}
	task_conds, err := l.svcCtx.TaskConditionModel.FindGroupConditonsByGroupId(l.ctx, req.GroupId)
	if err != nil {
		return nil, errorx.NewCodeErrorNoMsg(errorx.TASK_ERROR + 2)
	}
	copier.Copy(&task_conds_data, task_conds)

	//生成配置表
	task_conds_map := make(map[int64]*model.TaskCondition)
	for _, cond := range task_conds {
		task_conds_map[cond.Id] = cond
	}

	//获得任务分组的信息
	taskGroup, err := l.svcCtx.TaskGroupModel.FindOne(l.ctx, req.GroupId)

	if err != nil {
		return nil, errorx.NewCodeErrorNoMsg(errorx.TASK_ERROR + 1)
	}

	now := time.Now()

	//计算当前的batch id 和上一次的batch id,周期性的奖励最多只能保存1次未领，超过一次的不算
	var batch_id int64 = 1
	var prev_batch_id int64 = 0
	if taskGroup.Typ == "Y" {
		batch_id_t := utils.PrevCronTime(taskGroup.Cron, now)
		batch_id = batch_id_t.Unix()
		prev_batch_id_t := utils.PrevCronTime(taskGroup.Cron, batch_id_t)
		prev_batch_id = prev_batch_id_t.Unix()
	}

	copier.Copy(&resp.Data, taskGroup)

	//获得当前分组的所有的任务
	tasks, err := l.svcCtx.TaskModel.FindAllTaskByGroupId(l.ctx, taskGroup.Id)
	if err != nil {
		return nil, errorx.NewCodeErrorNoMsg(errorx.INTERNAL_ERROR)
	}

	tasks_data := []*types.TaskInfo{}

	task_count_map, err := getTaskCountMap(l.svcCtx.SqlConn, l.ctx, req.GroupId, batch_id, prev_batch_id, id)
	if err != nil {
		return nil, err
	}

	logx.Infof("task_count_map: %v", task_count_map)

	//获得以前是否领取记录，只算前两次的
	required_status, err := l.svcCtx.TaskStatusModel.FindAllGroupTaskStatus(l.ctx, req.GroupId, batch_id, prev_batch_id, id)
	switch err {
	case sqlx.ErrNotFound:
		break
	case nil:
		break
	default:
		return nil, errorx.NewCodeError(errorx.INTERNAL_ERROR, fmt.Sprintf("errx :%v", err.Error()))
	}

	//生成已领取的hash map 用来做排他处理
	req_status_map := make(map[string]bool)
	for _, s := range required_status {
		k := fmt.Sprintf("%v-%v-%v", s.GroupId, s.TaskId, s.BatchId)
		req_status_map[k] = true
	}
	logx.Infof("领取奖励的映射表: %v", req_status_map)
	logx.Infof("tasks: %v", tasks)

	valid_tasks := []*model.Task{}
	//获得当前分组下面的所有任务
	hasInsert := make(map[int64]int64)
	for _, task := range tasks {
		if _, ok := hasInsert[task.Id]; ok {
			continue
		}

		//前一期的奖励如果没有领，并且还完成所有的任务
		{
			k := fmt.Sprintf("%v-%v-%v", task.GroupId, task.Id, prev_batch_id)
			complete := isComplete(task.Id, prev_batch_id, task_count_map, task_conds_map)
			if _, ok := req_status_map[k]; !ok && complete {
				logx.Infof("完成的任务ID为:%v,完成状态为:%v,prev_batch_id:%v", task.Id, complete, prev_batch_id)
				valid_tasks = append(valid_tasks, task)
				hasInsert[task.Id] = prev_batch_id
				continue
			}
		}

		//当前这期是否完成
		{
			complete := isComplete(task.Id, batch_id, task_count_map, task_conds_map)
			if _, ok := hasInsert[task.Id]; !ok {
				logx.Infof("插入数据,完成的任务ID为:%v,完成状态为:%v,batch_id:%v", task.Id, complete, batch_id)
				valid_tasks = append(valid_tasks, task)
				hasInsert[task.Id] = batch_id
				continue
			}
		}
	}

	logx.Infof("hasInsert:%v", hasInsert)
	logx.Infof("----> valida_tasks:%v", len(valid_tasks))
	logx.Infof("----> task_count_map:%v", task_count_map)
	copier.Copy(&tasks_data, valid_tasks)

	for _, task := range tasks_data {
		for _, cond := range task_conds {
			k1 := fmt.Sprintf("%v-%v-%v", task.Id, hasInsert[task.Id], cond.TaskCondName)

			logx.Infof("----> k1:%v", k1)
			if cond.TaskId == task.Id {
				if desc, ok := cond_map[cond.TaskCondName]; ok {
					var cnt int64 = 0

					if count, ok := task_count_map[k1]; ok {
						cnt = count
					}

					c := types.TaskCondition{
						Name:  cond.TaskCondName,
						Desc:  desc,
						Count: cnt,
						Total: cond.Count,
					}
					task.Conditions = append(task.Conditions, c)
				}
			}
		}

		//当前任务的batch ID
		if bid, ok := hasInsert[task.Id]; ok {
			task.BatchId = bid
		} else {
			task.BatchId = batch_id
		}
		//当前的任务是否已经领取
		{
			k := fmt.Sprintf("%v-%v-%v", req.GroupId, task.Id, task.BatchId)
			if _, ok := req_status_map[k]; ok {
				task.Status = 1
			}
		}

		for _, cond := range task.Conditions {
			if cond.Count < cond.Total {
				goto END
			}
		}
		task.Completed = true

	END:
		//获得当前任务的所有奖励
		bonus, err := l.svcCtx.TaskBonusModel.FindAllTaskBonus(l.ctx, task.Id)
		if err != nil {
			return nil, errorx.NewCodeErrorNoMsg(errorx.INTERNAL_ERROR)
		}
		copier.Copy(&task.Bonus, bonus)
	}

	copier.Copy(&resp.Data.Tasks, tasks_data)
	return resp, nil
}
